﻿using System;
using CoreLibrary.Service;

namespace CoreLibrary.Cache {

    public abstract class AbstractCache : ServiceBase, ICache {

        protected abstract CacheItem<T> GetItem<T>(string key);

        public abstract void Remove(string key);
        public abstract void Put(string key, object value);
        public abstract void Put(string key, object value, TimeSpan expiration);
        
        public T GetAndEvict<T>(string key) {
            var value = Get<T>(key);
            Remove(key);
            return value;
        }

        public T Get<T>(string key) {
            var item = GetItem<T>(key);
            return !item.Found ? default(T) : item.Value;
        }

        public T Get<T>(string key, Func<T> itemCreator, bool cacheNewItem) {
            var item = GetItem<T>(key);
            if (!item.Found) {
                var value = itemCreator();
                if (value != null && cacheNewItem) {
                    Put(key, value);
                }
                return value;
            }
            return item.Value;
        }

        public T Get<T>(string key, Func<T> itemCreator, TimeSpan expiration, bool cacheNewItem) {
            var item = GetItem<T>(key);
            if (!item.Found) {
                var value = itemCreator();
                if (value != null && cacheNewItem) {
                    Put(key, value, expiration);
                }
                return value;
            }
            return item.Value;
        }

    }

}